package sf.config;

import io.netty.util.concurrent.DefaultThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

public class ReactiveTransactionTemplate {
    private Logger LOG = LoggerFactory.getLogger(ReactiveTransactionTemplate.class);

    @NonNull
    private final TransactionTemplate transactionTemplate;

    public ReactiveTransactionTemplate(@NonNull TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @NonNull
    public <T> Mono<T> execute(@NonNull TransactionCallback<T> action) {
        Scheduler scheduler = Schedulers.newSingle(new DefaultThreadFactory("transaction"));
        return Mono.fromCallable(() -> transactionTemplate.execute(action)).publishOn(scheduler).doFinally(t -> scheduler.dispose());
    }
}